package behaviorModel.visitor.demo;

import behaviorModel.visitor.demo.element.Book;
import behaviorModel.visitor.demo.element.Fruit;
import behaviorModel.visitor.demo.element.ItemElement;
import behaviorModel.visitor.demo.visit.ShoppingCartVisitor;
import behaviorModel.visitor.demo.visit.ShoppingCartVisitorImpl;

/**
 * 访问者模式是一种行为设计模式。访问者模式被用在针对一组相同类型对象的操作。
 * 优点是，可以把针对此对象的操作逻辑转移到另外一个类上。
 * <p>
 * 例如，思考一下添加不同类型商品的购物车，当点击结算的时候，
 * 它计算出所有不同商品需付的费用。现在，计算逻辑即为计算这些不同类型商品的价格。
 * 或者说通过访问者模式我们把此逻辑转移到了另外一个类上面。让我们实现这个访问者模式的例子。
 * <p>
 * 为了实现访问者模式，最先需要做的是创建能够被添加到购物车中代表不同类型商品(itemElement)的类。
 */
public class ShoppingCartClient {

    public static void main(String[] args) {
        ItemElement[] items = new ItemElement[]{new Book(20, "1234"), new Book(100, "5678"),
                new Fruit(10, 2, "Banana"), new Fruit(5, 5, "Apple")};

        int total = calculatePrice(items);
        System.out.println("Total Cost = " + total);
    }

    private static int calculatePrice(ItemElement[] items) {
        ShoppingCartVisitor visitor = new ShoppingCartVisitorImpl();
        int sum = 0;
        for (ItemElement item : items) {
            sum = sum + item.accept(visitor);
        }
        return sum;
    }

}